/************************************************************************
This file is part of Polar4linux
Copyright (C) 2010-2011 Eric jrdn2
Portions Copyright (C) 2007 Matti Juvonen <mpj@iki.fi> (RS400 Tools)
Portions Copyright (C) 2006 Jani Hursti <jani.hursti@hut.fi>,
Portions Copyright (C) 2001-2003 Tom Oliveira e Silva

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
************************************************************************/
#ifndef _POLARGRAPHS_H
#define _POLARGRAPHS_H

#include "RS400_all.h"
#include <sys/stat.h>
#include <string>
#include <QTimer>
#include <QDate>
#include <QMessageBox>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>

struct colorPanel
{
	QColor greyBG,transpWhite,transpRed,transpBlue;
	//sportzones colors
	QColor c0,c1,c2,c3,c4,c5;
};

struct graph_configuration
{
	colorPanel colors;
	int backgroundType;
	int boundType;
	float FCminDisplay,FCmaxDisplay;
	float SPEEDminDisplay,SPEEDmaxDisplay; //dynamic of the plot
	int user_hr_rest, user_hr_max;
	float user_speed;
	unsigned int sportzones[6];
};

class bbox
{
	public:
	//plot scales:
	int GRAPHOX,GRAPHOY;
	int GRAPHHEIGHT,GRAPHWIDTH;
	int LEGEND1_OX,LEGEND1_OY;
	int LEGEND2_OX,LEGEND2_OY;
	int HISTOGRAM_OX,HISTOGRAM_OY;
	int THUMBOX,THUMBOY;
	int THUMBWIDTH,THUMBHEIGHT;
	
	QFont myfont;
	int myfontsize;
	float ratio2normal;
};
/*
struct hrmData0
{
	rs400_session* hrm;
	rs400_pdd_content* pdd;
};


class hrmDataB
{
	public:
	hrmData0* loadHRM_n_PDD();
	removeData(hrmData0*); //avec refcount
	private:
	rs400_pdd_content* loadPDD();
	rs400_session* loadHRM();
	
	std::vector<rs400_session*> openedHRM;
	std::vector<rs400_session*> openedPDD;
};
*/

struct intervalStatistics
{
	unsigned int HRmin,HRmax,HRAverage;
	unsigned int speedMin,speedMax,speedAverage;
	float energy;
	unsigned int duration;
};

class hrm_data
{
  public:
	void  saveDATA();
	int   loadDATA(std::string path,QDate const &thedate,int exnum);
	void  computeStatistics();
	
	hrm_data():has_changed(0),exNumberForToday(0){};
  bool has_changed; //if selections have changed, tag it
  int exNumberForToday; //the calendar can deal with 10 exercises each day.

	//pointer on external data
  rs400_session *session;
  rs400_pdd_content *pddContent;

	intervalStatistics statsAll;
	intervalStatistics statsSelection;

	static const unsigned int nbbins=20;
	float histogram[nbbins];
};

float gimmeStep(float range, int targetSteps);
float gimmeStepTime(float range, int targetSteps);

#define BASE10AXIS 0
#define BASE60AXIS 1

class graph
{
public:
	virtual ~graph(){;}
	virtual void plot()=0;
	virtual void plotPreview(unsigned int, unsigned int)=0;
	virtual int mousePressEvent(Qt::MouseButton, QPointF &){return 1;} //0 did something, 1 did nothing
	virtual int mouseReleaseEvent(Qt::MouseButton, QPointF &){return 1;} //0 did something, 1 did nothing
	virtual int mouseMoveEvent (QPointF &){return 1;} //0 did something, 1 did nothing
	virtual void leave()=0; //todo when the mouse leaves the graph area
	
	void setScene(QGraphicsScene *_scene){scene=_scene;}
	bbox box;
	graph_configuration *default_graph_configuration;
	virtual void initializeAxesScales();
	
	void draw1sportzone(QPainter &painter,
											const int &sportzoneMax,const int &sportzoneMin,const QColor &SPcolor, 
											int &sumpix,const int &dynamic,
											const QString legend,const int &fontsize);
	void drawBG();
	void drawPolarBG();
	void drawGraphPaperBG();
	QString step2hms(float step);
	void drawAxisLeft(QString Legend, QColor LegendColor, int AxisType, float min, float max);
	void drawAxisRight(QString Legend, QColor LegendColor, int AxisType,float min, float max);
	void drawAxisBottom(QString Legend, QColor LegendColor,int AxisType, float min, float max);
	protected:
	QGraphicsScene *scene; //where to plot

	QPen gPen;
	QBrush gBrush;
	unsigned int* sportzone;
	float FCminDisplay,FCmaxDisplay,SPEEDminDisplay,SPEEDmaxDisplay; //dynamic of the plot
	int user_hr_rest, user_hr_max;
};

class lapsGraph:public graph
{
	public:
	lapsGraph(graph_configuration *default_graph_configuration0);
	lapsGraph(hrm_data &data, graph_configuration *default_graph_configuration0);
	virtual ~lapsGraph();
	virtual void plot();
	virtual void initializeAxesScales();
	void releaseData();
	void drawData();
	void drawAxes();
	virtual void plotPreview(unsigned int, unsigned int){;}
	virtual void leave(){;}

	private:
	hrm_data data;
};

class sessionGraph:public graph
{
	public:
	sessionGraph(graph_configuration *default_graph_configuration0);
	virtual ~sessionGraph(); //custom destructor, asks for save and releases data
	virtual void plot();
	virtual void plotPreview(unsigned int, unsigned int);
	virtual void initializeAxesScales();
	
	void addData(hrm_data &hr);
	void releaseData();
	hrm_data& dataNumber(unsigned int index);
	unsigned int dataSize();

	void drawHR();
	void drawSPEED();
	void drawLaps();
	void drawSelections();
	void drawHistograms();
	void drawLegends();
	void drawLegendsComparison();
	void drawAxes();
	void drawCursor(int x, int y);
	virtual int mousePressEvent(Qt::MouseButton button, QPointF &tmp1);
	virtual int mouseReleaseEvent(Qt::MouseButton button, QPointF &tmp1);
	virtual int mouseMoveEvent (QPointF &tmp1);
	virtual void leave();
	
	unsigned int NumPointsDisplay,recording_rateDisplay; //number of points of the curve that lasts the more

	std::vector<QGraphicsRectItem*> listeSelection; //selections in the screen space
	
		//plot laps:
	QGraphicsRectItem *rectLap;
	QGraphicsTextItem *textLap;
	
		//selection itm;
	QGraphicsRectItem* SelectionItm;
	bool selOK;
	QPointF initial;
	QPointF final;
	private:
	std::vector<hrm_data> data;
	std::vector<QColor> colors;
};

class advExoGraph:public graph
{
	public:
	advExoGraph(graph_configuration *default_graph_configuration0){default_graph_configuration=default_graph_configuration0;}
	virtual ~advExoGraph(){;}
	void setWorkingExercise(polarLINUXio_advancedExo*);
	virtual void plot();
	virtual void plotPreview(unsigned int, unsigned int){;}
	void drawAxes();
	virtual void leave(){;}
	polarLINUXio_advancedExo* exo; //advex or training
	//float FCminDisplay,FCmaxDisplay,SPEEDminDisplay,SPEEDmaxDisplay; //dynamic of the plot
	float totalTime;
	int hasSpeed;
	int hasTime;
};

class basicExoGraph:public graph
{
	public:
	basicExoGraph(graph_configuration *default_graph_configuration0){default_graph_configuration=default_graph_configuration0;}
	virtual ~basicExoGraph(){;}
	void setWorkingExercise(polarLINUXio_basic_exercise*);
	virtual void plot();
	virtual void plotPreview(unsigned int, unsigned int){;}
	void drawAxes();
	virtual void leave(){;}
	polarLINUXio_basic_exercise* exo; //advex or training
	float totalTime;
	int hasSpeed;
	int hasTime;
};

struct statisticsSportzone
{
	unsigned int timeInZones[10];
	unsigned int weekTime;
};


class yearStatsGraph:public graph
{
	public:
	yearStatsGraph(graph_configuration *default_graph_configuration0){default_graph_configuration=default_graph_configuration0;type=0;}
	virtual ~yearStatsGraph(){;}
	virtual void plot();
	void drawLegends();
	
	void drawAccumulatedTime();
	void drawStartTimes();
	void drawDurations();
	void drawHRates();
	void drawAxisYear(QString Legend, QColor LegendColor);
	virtual void plotPreview(unsigned int, unsigned int){;}
	virtual void leave(){;}

	//for statistics
	QDate startDate,endDate;
	std::vector<statisticsSportzone> SportzoneBars;
	std::vector<int> HRaverages;
	unsigned int totalTime;
	unsigned int NumExercises;
	unsigned int averageTime;
	unsigned int averageHR;
	unsigned int totalCalories;
	unsigned int averageStartTime;
	unsigned int maxtimeWeek;
	
	std::vector<float> startTimes;
	std::vector<float> durations;
	std::vector<float> HRates;
	
	int type;
};

#endif
